package pe.edu.upc.e41a.javasoft.jsf;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.validator.LengthValidator;

import org.primefaces.component.autocomplete.AutoComplete;
import org.primefaces.component.inputtext.InputText;
import org.primefaces.component.inputtextarea.InputTextarea;
import org.primefaces.component.message.Message;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.roo.addon.jsf.managedbean.RooJsfManagedBean;
import org.springframework.roo.addon.serializable.RooSerializable;

import pe.edu.upc.e41a.javasoft.domain.Categoria;
import pe.edu.upc.e41a.javasoft.domain.Publicacion;
import pe.edu.upc.e41a.javasoft.jsf.converter.CategoriaConverter;
import pe.edu.upc.e41a.javasoft.service.CategoriaService;

@Configurable
@ManagedBean(name = "categoriaBean")
@SessionScoped
@RooSerializable
@RooJsfManagedBean(entity = Categoria.class, beanName = "categoriaBean")
public class CategoriaBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@Autowired
	CategoriaService categoriaService;

	private String name = "Categorias";

	private Categoria categoria;

	private List<Categoria> allCategorias;

	private boolean dataVisible = false;

	private List<String> columns;

	//private boolean createDialogVisible = false;

	private List<Publicacion> selectedPublicacions;

	private List<Categoria> selectedCategorias;

	private TreeNode root;
	private TreeNode selectedNode;
	private Categoria categoriaArbol;
	private Categoria selectedCategoria;

	@PostConstruct
	public void init() {
		columns = new ArrayList<String>();
		columns.add("nombre");
		columns.add("descripcion");
		crearArbol(categoriaArbol,"-",root);
	}

	public String getName() {
		return name;
	}

	public List<String> getColumns() {
		return columns;
	}

	public List<Categoria> getAllCategorias() {
		return allCategorias;
	}

	public void setAllCategorias(List<Categoria> allCategorias) {
		this.allCategorias = allCategorias;
	}

	public String findAllCategorias() {
		allCategorias = categoriaService.findAllCategorias();
		dataVisible = !allCategorias.isEmpty();
		return null;
	}

	public boolean isDataVisible() {
		return dataVisible;
	}

	public void setDataVisible(boolean dataVisible) {
		this.dataVisible = dataVisible;
	}
	
	
	public void setTreeNode(TreeNode treeNode) {
		this.root = treeNode;
	}

	public TreeNode getRoot() {
		return root;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}
 
	public void displaySelectedSingle(ActionEvent event) {
		if (selectedNode != null) {
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Selected", selectedNode.getData().toString());

			FacesContext.getCurrentInstance().addMessage(null, message);

		}
	}
	
	public Categoria getCategoria() {
		if (categoria == null) {
			categoria = new Categoria();
		}
		return categoria;
	}

	public void setCategoria(Categoria categoria) {
		this.categoria = categoria;
	}

	public List<Publicacion> getSelectedPublicacions() {
		return selectedPublicacions;
	}

	public void setSelectedPublicacions(List<Publicacion> selectedPublicacions) {
		if (selectedPublicacions != null) {
			categoria.setPublicacions(new HashSet<Publicacion>(
					selectedPublicacions));
		}
		this.selectedPublicacions = selectedPublicacions;
	}

	public List<Categoria> getSelectedCategorias() {
		return selectedCategorias;
	}

	public void setSelectedCategorias(List<Categoria> selectedCategorias) {
		if (selectedCategorias != null) {
			categoria.setCategorias(new HashSet<Categoria>(selectedCategorias));
		}
		this.selectedCategorias = selectedCategorias;
	}

	public String onEdit() {
		if (categoria != null && categoria.getPublicacions() != null) {
			selectedPublicacions = new ArrayList<Publicacion>(
					categoria.getPublicacions());
		}
		if (categoria != null && categoria.getCategorias() != null) {
			selectedCategorias = new ArrayList<Categoria>(
					categoria.getCategorias());
		}
		return null;
	}

	/*public boolean isCreateDialogVisible() {
		return createDialogVisible;
	}

	public void setCreateDialogVisible(boolean createDialogVisible) {
		this.createDialogVisible = createDialogVisible;
	}*/

	public String displayList() {
	//	createDialogVisible = false;
		findAllCategorias();
		return "categoria";
	}

	public String displayCreateDialog() {
		categoria = new Categoria();
	//	createDialogVisible = true;
		return "categoria";
	}

	public String persist() {
		String message = "";
		fijarCategoria();
		if (categoria.getCodigo() != null) {
            //usuarioService.updateUsuario(usuario);
            //message =categoriaService.updateCategoria(categoria);
            //message = "Successfully updated";
        } else {
            //usuarioService.saveUsuario(usuario);
        	message = categoriaService.insertarCategoria(categoria);
            //message = "Successfully created";
        }
        
        if (message.equalsIgnoreCase("La categoría se registró exitosamente")) {
            FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, message,"");
            FacesContext.getCurrentInstance().addMessage(null, facesMessage);
            reset();
            crearArbol(categoriaArbol,"-",root);  
            
		} else {
			FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message,"");
            FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}
		//reset();
		
		//crearArbol(categoriaArbol,"-",root);
		//return findAllCategorias();
		return null;
	}

	public String delete() {
		categoriaService.deleteCategoria(categoria);
		FacesMessage facesMessage = new FacesMessage("Successfully deleted");
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		reset();
		return findAllCategorias();
	}

	public void reset() {
		categoria = new Categoria();
		selectedPublicacions = null;
		selectedCategorias = null;
		selectedCategoria=null;
		root=null;
		root = new DefaultTreeNode("Root", null);
		categoriaArbol=null;
		//createDialogVisible = false;
	}

	public void handleDialogClose(CloseEvent event) {
		reset();
	}

	public String crearArbol(Categoria categoria, String prefix,
			TreeNode nodoRef) {

		List<Categoria> listaCategoria = categoriaService
				.findCategoriasByPadre(categoria);
		if (listaCategoria.size() > 0) {
			Iterator it = listaCategoria.iterator();
			while (it.hasNext()) {
				if (root == null) {
					root = new DefaultTreeNode("Root", null);
				}
				Categoria category = (Categoria) it.next();
				TreeNode nodo = new DefaultTreeNode(category.getNombre(),
						nodoRef);
				// System.out.println(prefix+category.getNombre());
				crearArbol(category, prefix + "-", nodo);
			}
		}
		return null;
	}
	
	public void onNodeExpand(NodeExpandEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Expanded", event.getTreeNode().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);

	}

	public String getNodeChild() {
		return null;
	}

	public void onNodeCollapse(NodeCollapseEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Collapsed", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void onNodeSelect(NodeSelectEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Selected", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void onNodeUnselect(NodeUnselectEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Unselected", event.getTreeNode().getData().toString());

		FacesContext.getCurrentInstance().addMessage(null, message);
	}
	
	
	public void fijarCategoria() {
		if (selectedNode!=null) {
			String nodo = selectedNode.getData().toString();
			selectedCategoria = categoriaService.buscarCategoriaPorNombre(nodo);
			categoria.setPadre(selectedCategoria);
		}else {
			categoria.setPadre(selectedCategoria);
		}
		
	}

	public Categoria getSelectedCategoria() {
		return selectedCategoria;
	}

	public void setSelectedCategoria(Categoria selectedCategoria) {
		this.selectedCategoria = selectedCategoria;
	}

}
